class EventEmitter {
  constructor() {
    // handlers是一个map，用于存储事件与回调之间的对应关系
    this.handlers = {};
  }

  // on 监听 emit事件
  on(eventName, func) {
    // 先检查目标事件有没有对应的监听函数队列
    if (!this.handlers[eventName]) {
      // 如果没有 就设置一个空的数组
      this.handlers[eventName] = [];
    }

    // 把回调函数推入目标事件的监听函数队列里去
    this.handlers[eventName].push(func);
  }

  // emit 发送触发目标事件
  emit(eventName, ...args) {
    // 当我们发送 emit的时候, 执行队列里面的回调函数
    if (this.handlers[eventName]) {
      // 这里要对数据进行一次深拷贝
      const handlers = this.handlers[eventName].slice();
      // 判断如果有要监听的fun 就依次执行
      handlers.forEach((func) => {
        func(...args);
      });
    }
  }

  // off 解除绑定
  off(eventName, func) {
    const callbacks = this.handlers[eventName];
    // 找到指定的回调
    const index = callbacks.indexOf(func);
    if (index !== -1) {
      callbacks.splice(index, 1);
    }
  }

  // once 执行一次监听后立马销毁
  once(eventName, func) {
    // 封装改变一下解构 使他能够支持执行完毕后自动被移除
    const wrapper = (...args) => {
      func(...args);
      this.off(eventName, wrapper);
    };
    this.on(eventName, wrapper);
  }
}
